using System;
using System.Collections;
using System.Runtime.CompilerServices;
using System.Serialization;
using Awaiter;
using Nsb.Classes;
using jQueryApi;

namespace Tickles
{
    [IgnoreNamespace]
    public class Gig : Actor
    {
        public Gig()
        {
            Element = jQuery.FromHtml("<div class='Tickle'/>")
                ;
        }

        public TickleData Data
        {
            get { return Scoop(Element); }
        }

        public TickleData Scoop(jQueryObject el)
        {
            TickleData td = new TickleData();
            td.pos = el.Position();
            td.off = el.GetOffset();
            td.dim = new Dimension();
            td.dim.width = el.GetWidth();
            td.dim.height = el.GetHeight();
            td.selecTo = el.Plugin<Jewl>().SelecTo(new Dictionary("parent", true));
            td.html = (string) Script.Literal("{0}.outerHMTL", el[0]);
            return td;
        }

        private string Serialize()
        {
            return Json.Stringify(Data);
        }

        public void SaveAw(Await awp, string partitionKey, string rowKey)
        {
            FileBlobBase.StoreBlobStringAw(awp, partitionKey, rowKey, Serialize());
        }

        public static void RestoreAw(Await awp, string partitionKey, string rowKey)
        {
            new Await()
                .AddAw(FileBlobBase.RetrieveBlobStringAw, partitionKey, rowKey)
                .HandleDl(Exceptions.BlobLoadError, Await.RethrowAw)
                .AddDx(
                    delegate(Await aw)
                    {
                        string raw = (string) aw[PkgBase.ResultRx];
                        TickleData td = (TickleData) Json.Parse(raw);
                        InjectIntoPage(td);
                    })
                .Commit(awp);
        }

        public static Gig InjectIntoPage(TickleData td)
        {
            Gig tt = new Gig();
            jQueryObject where = jQuery.Select(td.selecTo);
            if (where.Length != 0)
            {
                tt.Element = jQuery.FromHtml(td.html);
                tt.AppendTo(where);
            }
            else
            {
                throw new Exception(Exceptions.Format(Exceptions.MissingDomElement, Exceptions.Fn(Script.Literal("arguments"))));
            }
            return tt;
        }

#pragma warning disable 108,114

        public Gig AppendTo(jQueryObject el)
        {
            Element.AppendTo(el);
            return this;
        }

        public Gig FromHtml(string html)
        {
            jQuery.FromHtml(html).AppendTo(Element);
            return this;
        }

#pragma warning restore 108,114
    }


    public sealed class TickleData
    {
        // ReSharper disable InconsistentNaming
        public Dimension dim;
        public string html;
        public jQueryPosition off;
        public jQueryPosition pos;
        public string selecTo;
        // ReSharper restore InconsistentNaming
    }

    public sealed class Dimension
    {
        // ReSharper disable InconsistentNaming
        public int height;
        public int width;
        // ReSharper restore InconsistentNaming
    }
}